import 'dart:async';

import 'package:flutter/material.dart';
import 'package:xws/utils/theme_util.dart';

/// 长按按钮
class HoldBtn extends StatefulWidget {
  const HoldBtn({
    Key? key,
    this.text,
    this.textStyle,
    this.child,
    this.onTap,
    this.onHold,
    this.padding,
    this.width,
    this.height,
    this.color,
    this.disabledColor,
    this.border,
    this.borderRadius,
    this.alignment,
    this.radius,
  }) : super(key: key);

  @override
  _HoldBtnState createState() => _HoldBtnState();

  final String? text;
  final TextStyle? textStyle;
  final Widget? child;
  final Function()? onTap;
  final Function()? onHold;
  final EdgeInsetsGeometry? padding;
  final double? width;
  final double? height;
  final Color? color;
  final Color? disabledColor;
  final BoxBorder? border;
  final BorderRadiusGeometry? borderRadius;
  final AlignmentGeometry? alignment;

  final double? radius;
}

class _HoldBtnState extends State<HoldBtn> {
  late DateTime _tapDownDate;

  Timer? _timer;

  @override
  void dispose() {
    _cancelTimer();
    super.dispose();
  }

  void _startTimer() {
    _timer = Timer.periodic(const Duration(milliseconds: 100), (Timer t) {
      if (t.tick > 10) {
        widget.onHold?.call();
      }
    });
  }

  void _cancelTimer() {
    _timer?.cancel();
    _timer = null;
  }

  void _onTapDown(TapDownDetails _) {
    _tapDownDate = DateTime.now();
    _startTimer();
  }

  void _onTapUp(TapUpDetails _) {
    _cancelTimer();
    final int duration = DateTime.now().difference(_tapDownDate).inMilliseconds;
    if (duration < 500) {
      widget.onTap?.call();
      return;
    }
  }

  void _onTapCancel() {
    _cancelTimer();
  }

  @override
  Widget build(BuildContext context) {
    Widget box = Container(
      width: widget.width,
      height: widget.height,
      padding: widget.padding ?? const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
      alignment: widget.alignment,
      child: widget.child ?? Text(widget.text ?? '', style: widget.textStyle),
      decoration: BoxDecoration(
        color: _color(context),
        border: widget.border,
        borderRadius: widget.borderRadius ?? BorderRadius.all(Radius.circular(widget.radius ?? 4)),
      ),
    );

    if (widget.onTap != null) {
      box = GestureDetector(
        child: box,
        onTapDown: _onTapDown,
        onTapUp: _onTapUp,
        onTapCancel: _onTapCancel,
      );
    }

    return box;
  }

  Color _color(BuildContext context) {
    if (widget.onTap == null) {
      return widget.disabledColor ?? theme(context).withOpacity(0.2);
    }

    return widget.color ?? theme(context);
  }
}
